home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /*
- * psnup -
- * Do n-up printing of PostScript files
- *
- * To compile:
- * cc psnup.c -o psnup
- *
- * Paul Haeberli - 1993
- */
- #include "stdio.h"
- #include "math.h"
- #include "ctype.h"
-
- #define DEFPWIDTH (72.0*8.50) /* page width and weight */
- #define DEFPHEIGHT (72.0*11.0)
-
- #define SPACE (72.0*0.2) /* space between */
- #define MARGIN (72.0*0.2) /* space around */
-
- #define SWIDTH (72.0*8.50) /* sheet width and height */
- #define SHEIGHT (72.0*11.0)
-
- #define INBUFSIZE 4096
- #define MAXPAGES 1000
-
- char buf[INBUFSIZE];
- int secstart[MAXPAGES];
- int secend[MAXPAGES];
- int trailstart;
- int trailend;
- float pwidth, pheight;
-
- void printheader(dosettrans)
- int dosettrans;
- {
- printf("%%!PS-Adobe-2.0\n");
- printf("%%%%EndComments\n");
- printf("/REALshowpage /showpage load def\n");
- printf("/showpage { } def\n");
- if(dosettrans)
- psprintcortab();
- }
-
- int indexpages(inf)
- FILE *inf;
- {
- int i, n, before, after;
-
- n = 0;
- trailstart = 0;
- trailend = 0;
- while(fgets(buf,INBUFSIZE,inf)) {
- if(strncmp(buf,"%%Page:",7) == 0) {
- after = ftell(inf);
- if(n>0)
- secend[n-1] = before;
- secstart[n] = after;
- n++;
- } else if(strncmp(buf,"%%Trailer",9) == 0) {
- after = ftell(inf);
- if(n>0)
- secend[n-1] = before;
- trailstart = after;
- trailend = sizeoffile(inf);
- return n;
- }
- before = ftell(inf);
- }
- secend[n-1] = ftell(inf);
- return n;
- }
-
- void putsection(inf,start,nbytes)
- FILE *inf;
- int start, nbytes;
- {
- int nr;
-
- fseek(inf,start,0);
- while(nbytes>0) {
- if(!fgets(buf,INBUFSIZE,inf)) {
- fprintf(stderr,"psnup: bad read in putsection\n");
- exit(1);
- }
- nr = strlen(buf);
- nbytes -= nr;
- if(buf[0] != '%')
- fputs(buf,stdout);
- }
- if(nbytes != 0) {
- fprintf(stderr,"psnup: strange read in putsection %d\n",nbytes);
- exit(1);
- }
- }
-
- void putpage(inf,pageno,npages)
- FILE *inf;
- int pageno, npages;
- {
- int nbytes;
-
- if(pageno<npages && pageno>=0) {
- nbytes = secend[pageno]-secstart[pageno];
- putsection(inf,secstart[pageno],nbytes);
- }
- }
-
- void dosave(inf)
- FILE *inf;
- {
- printf("gsave\n");
- }
-
- void dorestore(inf)
- FILE *inf;
- {
- if(trailstart)
- putsection(inf,trailstart,trailend-trailstart);
- printf("grestore\n");
- }
-
- void psnup(inf,npages,nx,ny)
- FILE *inf;
- int npages, nx, ny;
- {
- int x, y, nperside, nsides, pageno, side;
- float fscale, qx, qy, ox, oy;
-
- qx = (SWIDTH-2*MARGIN)/nx;
- qy = (SHEIGHT-2*MARGIN)/ny;
- nperside = nx*ny;
- nsides = 1+((npages-1)/nperside);
- if((qx/qy) < (pwidth/pheight))
- fscale = (qx-SPACE)/pwidth;
- else
- fscale = (qy-SPACE)/pheight;
- ox = MARGIN+(qx-pwidth*fscale)/2.0;
- oy = MARGIN+(qy-pheight*fscale)/2.0;
-
- /* put out the sheets */
- pageno = 0;
- for(side=0; side<nsides; ) {
- printf("%%%%Page: page%d %d\n",side+1,side+1);
- for(y=0; y<ny; y++) {
- for(x=0; x<nx; x++) {
- if(pageno<npages) {
- printf("gsave\n");
- printf("%f %f translate\n",x*qx+ox,(ny-1-y)*qy+oy);
- printf("%f %f scale\n",fscale,fscale);
-
- dosave(inf);
- printf("newpath\n");
- printf("%f %f moveto\n",0.0,0.0);
- printf("%f %f lineto\n",pwidth,0.0);
- printf("%f %f lineto\n",pwidth,pheight);
- printf("%f %f lineto\n",0.0,pheight);
- printf("closepath clip newpath\n");
- putsection(inf,0,secstart[0]);
- putpage(inf,pageno,npages);
- dorestore(inf);
-
- printf("0 setgray\n");
- printf("0.1 setlinewidth\n");
- printf("newpath\n");
- printf("%f %f moveto\n",0.0,0.0);
- printf("%f %f lineto\n",pwidth,0.0);
- printf("%f %f lineto\n",pwidth,pheight);
- printf("%f %f lineto\n",0.0,pheight);
- printf("closepath stroke\n");
- printf("grestore\n");
- }
- pageno++;
- }
- }
- printf("REALshowpage\n");
- side++;
- }
- }
-
- main(argc,argv)
- int argc;
- char **argv;
- {
- FILE *inf;
- int npages, i, dosettrans;
- int nx, ny;
-
- if(argc<4) {
- fprintf(stderr,"\nusage: psnup in.ps nx ny [-s pagesizex pagesizey] [-nosettrans] > out.ps\n");
- fprintf(stderr,"\nThis will print two by two array of pages on each side of the paper: \n");
- fprintf(stderr," psnup in.ps 2 2 > out.ps\n");
- fprintf(stderr,"\nYou can also specify the size of the input pages like this: \n");
- fprintf(stderr," psnup in.ps 1 2 -s 17.53 13.63 > out.ps\n");
- fprintf(stderr,"\n");
- exit(1);
- }
- nx = atoi(argv[2]);
- ny = atoi(argv[3]);
- pwidth = DEFPWIDTH;
- pheight = DEFPHEIGHT;
- dosettrans = 1;
- for(i=4; i<argc; i++) {
- if(argv[i][0] == '-') {
- switch(argv[i][1]) {
- case 's':
- i++;
- pwidth = 72.0*atof(argv[i]);
- i++;
- pheight = 72.0*atof(argv[i]);
- break;
- case 'n':
- dosettrans = 0;
- break;
- }
- }
- }
- inf = fopen(argv[1],"r");
- if(!inf) {
- fprintf(stderr,"psnup: can't open %s\n",argv[1]);
- exit(1);
- }
- npages = indexpages(inf);
-
- fprintf(stderr,"Document pages %d\n",npages);
- #ifdef DEBUG
- for(i=0; i<npages; i++)
- fprintf(stderr,"page %d start %d finish %d\n",i,secstart[i],secend[i]);
- fprintf(stderr,"trailstart %d trailend %d\n",trailstart,trailend);
- #endif
-
- if(npages == 0) {
- secend[0] = sizeoffile(inf);
- secstart[0] = 0;
- npages = 1;
- }
-
- /* put out the master preamble */
- psoutfile(stdout);
- printheader(dosettrans);
- psgsave();
-
- /* put out the pages*/
- psnup(inf,npages,nx,ny);
- psgrestore();
- printf("%%%%EOF\n");
- exit(0);
- }
-
-